package com.hrh.selectsystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hrh.selectsystem.common.ErrorCode;
import com.hrh.selectsystem.exception.BusinessException;
import com.hrh.selectsystem.mapper.ChoiceRecordMapper;
import com.hrh.selectsystem.mapper.MatchResultMapper;
import com.hrh.selectsystem.mapper.MentorMapper;
import com.hrh.selectsystem.mapper.StudentMapper;
import com.hrh.selectsystem.model.dto.matchResult.MatchRecordAddRequest;
import com.hrh.selectsystem.model.dto.matchResult.MatchRecordQueryRequest;
import com.hrh.selectsystem.model.entity.ChoiceRecord;
import com.hrh.selectsystem.model.entity.MatchResult;
import com.hrh.selectsystem.model.entity.Mentor;
import com.hrh.selectsystem.model.entity.Student;
import com.hrh.selectsystem.model.vo.MatchRecordQueryVO;
import com.hrh.selectsystem.service.MatchResultService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author hetongxue
* @description 针对表【match_result(匹配结果)】的数据库操作Service实现
* @createDate 2024-10-26 14:06:05
*/
@Service
@Slf4j
public class MatchResultServiceImpl extends ServiceImpl<MatchResultMapper, MatchResult>
    implements MatchResultService{

    @Resource
    private MentorMapper mentorMapper;
    @Resource
    private MatchResultMapper matchResultMapper;
    @Resource
    private ChoiceRecordMapper choiceRecordMapper;
    @Resource
    private StudentMapper studentMapper;

    /**
     * 提交选择信息
     * @param matchRecordAddList
     * @param mentorId
     * @return
     */
    @Override
    @Transactional
    public Boolean submitChoice(List<MatchRecordAddRequest> matchRecordAddList, Long mentorId, Integer roundNumber) {
        // 查询导师信息
        QueryWrapper<Mentor> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", mentorId);
        Mentor mentor = mentorMapper.selectOne(queryWrapper);

        if (mentor == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "导师不存在");
        }

        // 判断当前导师名额数
        Integer mentorQuota = mentor.getMentorquota();
        Integer selectedCount = mentor.getSelectedquota();
        int quota = mentorQuota - selectedCount;

        if (quota == 0){
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "导师名额已满");
        }

        // 取出matchRecordList的数据
        List<Map<Long, Boolean>> matchRecordList = matchRecordAddList.stream()
                .map(matchRecordAddRequest -> {
                    Map<Long, Boolean> map = new HashMap<>();
                    map.put(matchRecordAddRequest.getStudentid(),
                            matchRecordAddRequest.getChoice());
                    return map;
                })
                .collect(Collectors.toList());

        // 取出matchRecordList里choice为true的数据
        List<Map<Long, Boolean>> selectedList = matchRecordList.stream()
                .filter(map -> map.values().stream().anyMatch(Boolean::booleanValue))
                .collect(Collectors.toList());

        // 取出matchRecordList里choice为false的数据
        List<Map<Long, Boolean>> rejectedList = matchRecordList.stream()
                .filter(map -> map.values().stream().noneMatch(Boolean::booleanValue))
                .collect(Collectors.toList());

        // 判断是否超过配额
        if (selectedList.size() > quota){
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "导师名额不足");
        }

        // 匹配成功结果存入数据库
        selectedList.forEach(map -> {
            map.forEach((studentId, choice) -> {
                MatchResult matchResult = new MatchResult();
                matchResult.setStudentid(studentId);
                matchResult.setMentorid(mentorId);
                matchResult.setChoiceorder(roundNumber);
                //打印matchResult信息
                log.info("matchResult: {}", matchResult);
                matchResultMapper.insert(matchResult);
            });
        });


        // 更新导师已选人数
        mentorMapper.updateSelectedQuota(mentorId, selectedList.size());

        // selectedList里的学生id更新choice_record表学生申请状态
        selectedList.forEach(map -> {
            map.forEach((studentId, choice) -> {
                updateChoiceRecordStatus(studentId, roundNumber, choice);
            });
        });
        // rejectedList里的学生id更新choice_record表学生申请状态
        rejectedList.forEach(map -> {
            map.forEach((studentId, choice) -> {
                updateChoiceRecordStatus(studentId, roundNumber, choice);
            });
        });

        return true;
    }

    /**
     * 更新choice_record表学生申请状态
     * @param studentId
     * @param roundNumber
     * @param choice
     */
    private void updateChoiceRecordStatus(Long studentId, Integer roundNumber, Boolean choice) {
        QueryWrapper<ChoiceRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("studentid", studentId);
        ChoiceRecord choiceRecord = choiceRecordMapper.selectOne(queryWrapper);
        String status;
        String statusEnd = "ended";
        if (!choice){
            status = "rejected";
        } else {
            status = "accepted";
        }
        if (roundNumber == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "轮次参数错误");
        }
        if (status.equals("accepted")){
            if (roundNumber == 1) {
                choiceRecord.setFirststatus(status);
                choiceRecord.setSecondstatus(statusEnd);
                choiceRecord.setThirdstatus(statusEnd);
            } else if (roundNumber == 2) {
                choiceRecord.setSecondstatus(status);
                choiceRecord.setThirdstatus(statusEnd);
            } else if (roundNumber == 3) {
                choiceRecord.setThirdstatus(status);
            }
        }
        if (status.equals("rejected")){
            if (roundNumber == 1) {
                choiceRecord.setFirststatus(status);
            } else if (roundNumber == 2) {
                choiceRecord.setSecondstatus(status);
            } else if (roundNumber == 3) {
                choiceRecord.setThirdstatus(status);
            }
        }
        choiceRecordMapper.updateById(choiceRecord);
    }

    /**
     * 获取学生已匹配的导师
     * @param studentId
     * @return
     */
    @Override
    public Mentor getAcceptedMentor(Long studentId) {
        QueryWrapper<MatchResult> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("studentid", studentId);
        MatchResult matchResult = matchResultMapper.selectOne(queryWrapper);
        if (matchResult == null){
            return null;
        }
        Long mentorId = matchResult.getMentorid();
        return mentorMapper.selectById(mentorId);
    }

    /**
     * 获取学生已匹配的导师
     * @param matchRecordQueryRequest
     * @param current
     * @param size
     * @return
     */
    @Override
    public Page<MatchRecordQueryVO> listMatchRecordByPage(MatchRecordQueryRequest matchRecordQueryRequest, long current, long size) {
        //region
//        String studentaccount = matchRecordQueryRequest.getStudentaccount();
//        String studentname = matchRecordQueryRequest.getStudentname();
//        String mentoraccount = matchRecordQueryRequest.getMentoraccount();
//        String mentorname = matchRecordQueryRequest.getMentorname();
//        Integer round = matchRecordQueryRequest.getRound();
//
//        // 查询结果表
//        QueryWrapper<MatchResult> queryWrapper = new QueryWrapper<>();
//        if (round != null){
//            queryWrapper.eq(round >0 && round <= 3 , "choiceorder", round);
//        }
//
//        List<MatchResult> matchResultList = matchResultMapper.selectList(queryWrapper);
//
//        // 查询学生表和导师表
//        List<Long> studentIdList = matchResultList.stream()
//                .map(MatchResult::getStudentid)
//                .distinct()
//                .collect(Collectors.toList());
//
//        List<Long> mentorIdList = matchResultList.stream()
//                .map(MatchResult::getMentorid)
//                .distinct()
//                .collect(Collectors.toList());
//
//        QueryWrapper<Student> studentQueryWrapper = new QueryWrapper<>();
//        studentQueryWrapper.like(StringUtils.isNotBlank(studentname), "studentname", studentname);
//        studentQueryWrapper.eq(StringUtils.isNotBlank(studentaccount), "studentaccount", studentaccount);
//        QueryWrapper<Mentor> mentorQueryWrapper = new QueryWrapper<>();
//        mentorQueryWrapper.like(StringUtils.isNotBlank(mentorname), "mentorname", mentorname);
//        mentorQueryWrapper.eq(StringUtils.isNotBlank(mentoraccount), "mentoraccount", mentoraccount);
//
//        List<Student> studentList = studentMapper.selectList(studentQueryWrapper.in("id", studentIdList));
//        List<Mentor> mentorList = mentorMapper.selectList(mentorQueryWrapper.in("id", mentorIdList));
//
//        // 组装VO
//        List<MatchRecordQueryVO> matchRecordQueryVOList = matchResultList.stream().map(matchResult -> {
//            Long studentId = matchResult.getStudentid();
//            Long mentorId = matchResult.getMentorid();
//            Student student = studentList.stream().filter(s -> s.getId().equals(studentId)).findFirst().orElse(null);
//            Mentor mentor = mentorList.stream().filter(m -> m.getId().equals(mentorId)).findFirst().orElse(null);
//            return MatchResultServiceImpl.createMatchRecordQueryVO(matchResult, student, mentor);
//        }).collect(Collectors.toList());
//
//        // 返回分页
//        Page<MatchRecordQueryVO> matchRecordQueryVOPage = new Page<>(current, size, matchRecordQueryVOList.size());
//        matchRecordQueryVOPage.setRecords(matchRecordQueryVOList);
//        return matchRecordQueryVOPage;
        //endregion
        String studentaccount = matchRecordQueryRequest.getStudentaccount();
        String studentname = matchRecordQueryRequest.getStudentname();
        String mentoraccount = matchRecordQueryRequest.getMentoraccount();
        String mentorname = matchRecordQueryRequest.getMentorname();
        Integer round = matchRecordQueryRequest.getRound();

        // 创建分页对象
        Page<MatchResult> page = new Page<>(current, size);

        // 构建查询条件
        QueryWrapper<MatchResult> queryWrapper = new QueryWrapper<>();
        if (round != null) {
            queryWrapper.eq(round > 0 && round <= 3, "choiceorder", round);
        }
        if (StringUtils.isNotBlank(studentaccount)) {
            queryWrapper.eq("studentaccount", studentaccount);
        }
        if (StringUtils.isNotBlank(mentoraccount)) {
            queryWrapper.eq("mentoraccount", mentoraccount);
        }

        // 先查询总记录数
        long total = matchResultMapper.selectCount(queryWrapper);
        int totalPages = (int) Math.ceil((double) total / size);

        // 如果请求的页码大于总页数，返回空值
        if (current > totalPages) {
            Page<MatchRecordQueryVO> emptyPage = new Page<>(current, size, total);
            emptyPage.setRecords(Collections.emptyList());
            return emptyPage;
        }

        // 查询结果表并进行分页
        Page<MatchResult> matchResultPage = matchResultMapper.selectPage(page, queryWrapper);
        List<MatchResult> matchResultList = matchResultPage.getRecords();

        // 查询学生表和导师表
        List<Long> studentIdList = matchResultList.stream()
                .map(MatchResult::getStudentid)
                .distinct()
                .collect(Collectors.toList());

        List<Long> mentorIdList = matchResultList.stream()
                .map(MatchResult::getMentorid)
                .distinct()
                .collect(Collectors.toList());

        QueryWrapper<Student> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.like(StringUtils.isNotBlank(studentname), "studentname", studentname);
        QueryWrapper<Mentor> mentorQueryWrapper = new QueryWrapper<>();
        mentorQueryWrapper.like(StringUtils.isNotBlank(mentorname), "mentorname", mentorname);

        List<Student> studentList = studentMapper.selectList(studentQueryWrapper.in("id", studentIdList));
        List<Mentor> mentorList = mentorMapper.selectList(mentorQueryWrapper.in("id", mentorIdList));

        // 组装VO
        List<MatchRecordQueryVO> matchRecordQueryVOList = matchResultList.stream().map(matchResult -> {
            Long studentId = matchResult.getStudentid();
            Long mentorId = matchResult.getMentorid();
            Student student = studentList.stream().filter(s -> s.getId().equals(studentId)).findFirst().orElse(null);
            Mentor mentor = mentorList.stream().filter(m -> m.getId().equals(mentorId)).findFirst().orElse(null);
            return MatchResultServiceImpl.createMatchRecordQueryVO(matchResult, student, mentor);
        }).collect(Collectors.toList());

        // 返回分页结果
        Page<MatchRecordQueryVO> matchRecordQueryVOPage = new Page<>(current, size, matchResultPage.getTotal());
        matchRecordQueryVOPage.setRecords(matchRecordQueryVOList);
        return matchRecordQueryVOPage;
    }

    /**
     * 强制匹配
     * @param studentId
     * @param mentorId
     * @return
     */
    @Override
    public boolean forceMatch(long studentId, long mentorId) {
        //查询当前导师是否有名额
        Mentor mentor = mentorMapper.selectById(mentorId);
        if (mentor.getMentorquota() <= mentor.getSelectedquota()){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "该导师已满额");
        }
        //查询当前学生是否已选择导师
        QueryWrapper<MatchResult> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("studentid", studentId);
        MatchResult matchResult = matchResultMapper.selectOne(queryWrapper);
        if (matchResult != null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "学生已选择导师");
        }
        //强行匹配
        MatchResult matchResultForce = new MatchResult();
        matchResultForce.setStudentid(studentId);
        matchResultForce.setMentorid(mentorId);
        matchResultForce.setChoiceorder(4);//管理员强制匹配的，轮次为4
        matchResultMapper.insert(matchResultForce);


        //更新导师已选人数
        mentorMapper.updateSelectedQuota(mentorId, 1);
        return true;
    }

    /**
     * 组装
     * @param matchResult
     * @param student
     * @param mentor
     */
    private static MatchRecordQueryVO createMatchRecordQueryVO(MatchResult matchResult, Student student, Mentor mentor) {
        String studentAccount = student.getStudentaccount();
        String studentName = student.getStudentname();
        String studentClass = student.getStudentclass();
        String studentCollege = student.getStudentcollege();
        String studentsex = student.getGender();
        String mentorAccount = mentor.getMentoraccount();
        String mentorName = mentor.getMentorname();
        String mentorCollege = mentor.getMentorcollege();
        String mentorsex = mentor.getGender();
        Integer round = matchResult.getChoiceorder();

        MatchRecordQueryVO matchRecordQueryVO = new MatchRecordQueryVO();
        matchRecordQueryVO.setStudentaccount(studentAccount);
        matchRecordQueryVO.setStudentname(studentName);
        matchRecordQueryVO.setStudentclass(studentClass);
        matchRecordQueryVO.setStudentcollege(studentCollege);
        matchRecordQueryVO.setStudentsex(studentsex);
        matchRecordQueryVO.setMentoraccount(mentorAccount);
        matchRecordQueryVO.setMentorname(mentorName);
        matchRecordQueryVO.setMentorsex(mentorsex);
        matchRecordQueryVO.setMentorcollege(mentorCollege);
        matchRecordQueryVO.setRound(round);

        return matchRecordQueryVO;
    }
}




